package edu.oregonstate.cartography.gui; import com.fizzysoft.sdu.RecentDocumentsManager; import edu.oregonstate.cartography.app.FileUtils; import edu.oregonstate.cartography.app.GeometryUtils; import edu.oregonstate.cartography.geometryexport.ShapeExporter; import edu.oregonstate.cartography.geometryimport.GeometryCollectionImporter; import edu.oregonstate.cartography.geometryimport.ShapeImporter; import edu.oregonstate.cartography.grid.ESRIASCIIGridExporter; import edu.oregonstate.cartography.grid.EsriASCIIGridReader; import edu.oregonstate.cartography.grid.Grid; import edu.oregonstate.cartography.grid.Model; import edu.oregonstate.cartography.grid.Model.ForegroundVisualization; import edu.oregonstate.cartography.grid.WorldFileExporter; import edu.oregonstate.cartography.grid.operators.IlluminatedContoursOperator; import edu.oregonstate.cartography.grid.operators.NormalMapOperator; import edu.oregonstate.cartography.grid.operators.NormalMapOperator.Channel; import edu.oregonstate.cartography.grid.operators.PlanObliqueOperator; import edu.oregonstate.cartography.simplefeatures.GeometryCollection; import edu.oregonstate.cartography.simplefeatures.LineString; import edu.oregonstate.cartography.simplefeatures.PlanObliqueShearing; import edu.oregonstate.cartography.simplefeatures.Point; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.Preferences; import javax.imageio.ImageIO; import javax.swing.Icon; import javax.swing.JMenuItem; import javax.swing.JOptionPane; /** * Shades a DEM generalizedGrid using weighted Laplacian Pyramids. Results are * displayed in this JFrame with options for user input. * * @author Charles Preppernau and Bernie Jenny, Oregon State University */ public class MainWindow extends javax.swing.JFrame { private static final String OPEN_ERROR_MESSAGE = "Could not open the terrain file."; private static final String SAVE_IMAGE_ERROR_MESSAGE = "Could not save the image file."; private static final String SAVE_TERRAIN_ERROR_MESSAGE = "Could not save the terrain file."; private final Model model; private SettingsDialog settingsDialog = null; private RecentDocumentsManager rdm; private final ProgressPanel progressPanel; /** * Constructor for the JFrame. Initializes components and sets up the * default color gradient. * * @param model model object */ public MainWindow(Model model) { this.model = model; initRecentDocumentsMenu(); initComponents(); // hide menu with experimental features menuBar.remove(experimentalMenu); // get menu keyboard events from owned dialogs DialogUtil.setupDialogActions(menuBar); progressPanel = new ProgressPanel(); progressPanel.setOpaque(false); setGlassPane(progressPanel); progressPanel.setVisible(false); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; imageResolutionPanel = new javax.swing.JPanel(); javax.swing.JLabel jLabel1 = new javax.swing.JLabel(); imageResolutionSpinner = new javax.swing.JSpinner(); scaleGridPanel = new javax.swing.JPanel(); javax.swing.JLabel jLabel8 = new javax.swing.JLabel(); scaleTerrainFormattedTextField = new javax.swing.JFormattedTextField(); javax.swing.JLabel jLabel9 = new javax.swing.JLabel(); offsetGridPanel = new javax.swing.JPanel(); javax.swing.JLabel jLabel10 = new javax.swing.JLabel(); offsetTerrainFormattedTextField = new javax.swing.JFormattedTextField(); javax.swing.JLabel jLabel11 = new javax.swing.JLabel(); voidGridPanel = new javax.swing.JPanel(); javax.swing.JLabel jLabel12 = new javax.swing.JLabel(); voidGridFormattedTextField = new javax.swing.JFormattedTextField(); javax.swing.JLabel jLabel13 = new javax.swing.JLabel(); navigableImagePanel = new edu.oregonstate.cartography.gui.NavigableImagePanel(); menuBar = new javax.swing.JMenuBar(); javax.swing.JMenu fileMenu = new javax.swing.JMenu(); javax.swing.JMenuItem openMenuItem = new javax.swing.JMenuItem(); openRecentMenu = rdm.createOpenRecentMenu(); javax.swing.JPopupMenu.Separator jSeparator1 = new javax.swing.JPopupMenu.Separator(); saveGridMenuItem = new javax.swing.JMenuItem(); saveGeneralizedGridMenuItem = new javax.swing.JMenuItem(); saveLocalGridMenuItem = new javax.swing.JMenuItem(); saveDownsampledMenu = new javax.swing.JMenu(); javax.swing.JPopupMenu.Separator jSeparator5 = new javax.swing.JPopupMenu.Separator(); javax.swing.JMenu saveImageMenu = new javax.swing.JMenu(); saveTIFFImageMenuItem = new javax.swing.JMenuItem(); savePNGImageMenuItem = new javax.swing.JMenuItem(); javax.swing.JMenu saveContoursMenu = new javax.swing.JMenu(); saveTIFFContoursMenuItem = new javax.swing.JMenuItem(); savePNGContoursMenuItem = new javax.swing.JMenuItem(); javax.swing.JMenu saveContoursMenu1 = new javax.swing.JMenu(); saveTIFFNormalMapMenuItem = new javax.swing.JMenuItem(); savePNGNormalMapMenuItem = new javax.swing.JMenuItem(); editMenu = new javax.swing.JMenu(); scaleGridMenuItem = new javax.swing.JMenuItem(); offsetGridMenuItem = new javax.swing.JMenuItem(); voidGridMenuItem = new javax.swing.JMenuItem(); viewMenu = new javax.swing.JMenu(); viewResetMenuItem = new javax.swing.JMenuItem(); javax.swing.JPopupMenu.Separator jSeparator4 = new javax.swing.JPopupMenu.Separator(); viewZoomInMenuItem = new javax.swing.JMenuItem(); viewZoomOutMenuItem = new javax.swing.JMenuItem(); javax.swing.JMenu infoMenu = new javax.swing.JMenu(); settingsMenuItem = new javax.swing.JMenuItem(); javax.swing.JPopupMenu.Separator jSeparator3 = new javax.swing.JPopupMenu.Separator(); terrainInfoMenuItem = new javax.swing.JMenuItem(); javax.swing.JPopupMenu.Separator jSeparator2 = new javax.swing.JPopupMenu.Separator(); infoMenuItem = new javax.swing.JMenuItem(); experimentalMenu = new javax.swing.JMenu(); planObliqueFeaturesMenuItem = new javax.swing.JMenuItem(); savePlanObliqueMenuItem = new javax.swing.JMenuItem(); imageResolutionPanel.setLayout(new java.awt.GridBagLayout()); jLabel1.setText("Image resolution relative to terrain model size:"); imageResolutionPanel.add(jLabel1, new java.awt.GridBagConstraints()); imageResolutionSpinner.setModel(new javax.swing.SpinnerNumberModel(1, 1, 25, 1)); imageResolutionPanel.add(imageResolutionSpinner, new java.awt.GridBagConstraints()); scaleGridPanel.setLayout(new java.awt.GridBagLayout()); jLabel8.setText("Scale Factor:"); scaleGridPanel.add(jLabel8, new java.awt.GridBagConstraints()); scaleTerrainFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter())); scaleTerrainFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28)); scaleTerrainFormattedTextField.setValue(new Float(1)); scaleGridPanel.add(scaleTerrainFormattedTextField, new java.awt.GridBagConstraints()); jLabel9.setFont(jLabel9.getFont().deriveFont(jLabel9.getFont().getSize()-2f)); jLabel9.setText("All values in the terrain grid are scaled by this factor."); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); scaleGridPanel.add(jLabel9, gridBagConstraints); offsetGridPanel.setLayout(new java.awt.GridBagLayout()); jLabel10.setText("Value to Add:"); offsetGridPanel.add(jLabel10, new java.awt.GridBagConstraints()); offsetTerrainFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter())); offsetTerrainFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28)); offsetTerrainFormattedTextField.setValue(new Float(1)); offsetGridPanel.add(offsetTerrainFormattedTextField, new java.awt.GridBagConstraints()); jLabel11.setFont(jLabel11.getFont().deriveFont(jLabel11.getFont().getSize()-2f)); jLabel11.setText("The value entered is added to all values in the terrain grid."); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); offsetGridPanel.add(jLabel11, gridBagConstraints); voidGridPanel.setLayout(new java.awt.GridBagLayout()); jLabel12.setText("Mark this value as void:"); voidGridPanel.add(jLabel12, new java.awt.GridBagConstraints()); voidGridFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter())); voidGridFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28)); voidGridFormattedTextField.setValue(new Float(0)); voidGridPanel.add(voidGridFormattedTextField, new java.awt.GridBagConstraints()); jLabel13.setFont(jLabel13.getFont().deriveFont(jLabel13.getFont().getSize()-2f)); jLabel13.setText("All values in the grid with the selected value will be set to the void value."); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); voidGridPanel.add(jLabel13, gridBagConstraints); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("Pyramid Shader"); setMinimumSize(new java.awt.Dimension(700, 700)); navigableImagePanel.setNavigationImageEnabled(false); getContentPane().add(navigableImagePanel, java.awt.BorderLayout.CENTER); fileMenu.setText("File"); fileMenu.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { fileMenuMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); openMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); openMenuItem.setText("Open Grid…"); openMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { openMenuItemActionPerformed(evt); } }); fileMenu.add(openMenuItem); openRecentMenu.setText("Open Recent"); fileMenu.add(openRecentMenu); fileMenu.add(jSeparator1); saveGridMenuItem.setText("Save Grid…"); saveGridMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveGridMenuItemActionPerformed(evt); } }); fileMenu.add(saveGridMenuItem); saveGeneralizedGridMenuItem.setText("Save Generalized Grid…"); saveGeneralizedGridMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveGeneralizedGridMenuItemActionPerformed(evt); } }); fileMenu.add(saveGeneralizedGridMenuItem); saveLocalGridMenuItem.setText("Save Locally Filtered Grid…"); saveLocalGridMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveLocalGridMenuItemActionPerformed(evt); } }); fileMenu.add(saveLocalGridMenuItem); saveDownsampledMenu.setText("Save Downsampled Grid"); saveDownsampledMenu.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { saveDownsampledMenuMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); fileMenu.add(saveDownsampledMenu); fileMenu.add(jSeparator5); saveImageMenu.setText("Save Image"); saveTIFFImageMenuItem.setText("TIFF"); saveTIFFImageMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveTIFFImageMenuItemActionPerformed(evt); } }); saveImageMenu.add(saveTIFFImageMenuItem); savePNGImageMenuItem.setText("PNG"); savePNGImageMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { savePNGImageMenuItemActionPerformed(evt); } }); saveImageMenu.add(savePNGImageMenuItem); fileMenu.add(saveImageMenu); saveContoursMenu.setText("Save Contour Image"); saveTIFFContoursMenuItem.setText("TIFF"); saveTIFFContoursMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveTIFFContoursMenuItemActionPerformed(evt); } }); saveContoursMenu.add(saveTIFFContoursMenuItem); savePNGContoursMenuItem.setText("PNG"); savePNGContoursMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { savePNGContoursMenuItemActionPerformed(evt); } }); saveContoursMenu.add(savePNGContoursMenuItem); fileMenu.add(saveContoursMenu); saveContoursMenu1.setText("Save Normal Map"); saveTIFFNormalMapMenuItem.setText("TIFF"); saveTIFFNormalMapMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveTIFFNormalMapMenuItemActionPerformed(evt); } }); saveContoursMenu1.add(saveTIFFNormalMapMenuItem); savePNGNormalMapMenuItem.setText("PNG"); savePNGNormalMapMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { savePNGNormalMapMenuItemActionPerformed(evt); } }); saveContoursMenu1.add(savePNGNormalMapMenuItem); fileMenu.add(saveContoursMenu1); menuBar.add(fileMenu); editMenu.setText("Edit"); editMenu.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { editMenuMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); scaleGridMenuItem.setText("Scale Grid Values…"); scaleGridMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { scaleGridMenuItemActionPerformed(evt); } }); editMenu.add(scaleGridMenuItem); offsetGridMenuItem.setText("Offset Grid Values…"); offsetGridMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { offsetGridMenuItemActionPerformed(evt); } }); editMenu.add(offsetGridMenuItem); voidGridMenuItem.setText("Void Grid Values…"); voidGridMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { voidGridMenuItemActionPerformed(evt); } }); editMenu.add(voidGridMenuItem); menuBar.add(editMenu); viewMenu.setText("View"); viewMenu.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { viewMenuMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); viewResetMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_0, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); viewResetMenuItem.setText("Reset View"); viewResetMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { viewResetMenuItemActionPerformed(evt); } }); viewMenu.add(viewResetMenuItem); viewMenu.add(jSeparator4); viewZoomInMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_PLUS, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); viewZoomInMenuItem.setText("Zoom In"); viewZoomInMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { viewZoomInMenuItemActionPerformed(evt); } }); viewMenu.add(viewZoomInMenuItem); viewZoomOutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_MINUS, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); viewZoomOutMenuItem.setText("Zoom Out"); viewZoomOutMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { viewZoomOutMenuItemActionPerformed(evt); } }); viewMenu.add(viewZoomOutMenuItem); menuBar.add(viewMenu); infoMenu.setText("Window"); infoMenu.addMenuListener(new javax.swing.event.MenuListener() { public void menuSelected(javax.swing.event.MenuEvent evt) { infoMenuMenuSelected(evt); } public void menuDeselected(javax.swing.event.MenuEvent evt) { } public void menuCanceled(javax.swing.event.MenuEvent evt) { } }); settingsMenuItem.setText("Show Settings"); settingsMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { settingsMenuItemActionPerformed(evt); } }); infoMenu.add(settingsMenuItem); infoMenu.add(jSeparator3); terrainInfoMenuItem.setText("Grid Info"); terrainInfoMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { terrainInfoMenuItemActionPerformed(evt); } }); infoMenu.add(terrainInfoMenuItem); infoMenu.add(jSeparator2); infoMenuItem.setText("Info"); infoMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { infoMenuItemActionPerformed(evt); } }); infoMenu.add(infoMenuItem); menuBar.add(infoMenu); experimentalMenu.setText("Experimental"); planObliqueFeaturesMenuItem.setText("Plan Oblique Lines…"); planObliqueFeaturesMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { planObliqueFeaturesMenuItemActionPerformed(evt); } }); experimentalMenu.add(planObliqueFeaturesMenuItem); savePlanObliqueMenuItem.setText("Save Plan Oblique… "); savePlanObliqueMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { savePlanObliqueMenuItemActionPerformed(evt); } }); experimentalMenu.add(savePlanObliqueMenuItem); menuBar.add(experimentalMenu); setJMenuBar(menuBar); pack(); }// </editor-fold>//GEN-END:initComponents private void initRecentDocumentsMenu() { final String APPNAME = "PyramidShader"; rdm = new RecentDocumentsManager() { private Preferences getPreferences() { return Preferences.userNodeForPackage(MainWindow.class); } @Override protected byte[] readRecentDocs() { return getPreferences().getByteArray("RecentDocuments" + APPNAME, null); } @Override protected void writeRecentDocs(byte[] data) { getPreferences().putByteArray("RecentDocuments" + APPNAME, data); } @Override protected void openFile(File file, ActionEvent event) { if (file != null) { try { openGrid(file.getCanonicalPath()); } catch (IOException ex) { ErrorDialog.showErrorDialog(OPEN_ERROR_MESSAGE, "Error", ex, null); } } } @Override protected Icon getFileIcon(File file) { return null; } }; } // A SwingWorker for rendering the background image to a file. class FileRenderer extends SwingWorkerWithProgressIndicatorDialog<Void> { private final BufferedImage backgroundImage; private final String filePath; private final String fileFormat; protected FileRenderer(BufferedImage backgroundImage, String filePath, String fileFormat, Frame owner) { super(owner, "", "", true); this.backgroundImage = backgroundImage; this.filePath = filePath; this.fileFormat = fileFormat; this.setIndeterminate(false); this.setCancellable(false); } @Override public Void doInBackground() { if (model.getGeneralizedGrid() != null) { // initialize the progress dialog start(); model.renderBackgroundImage(backgroundImage, this); } return null; } @Override protected void done() { try { if (!isCancelled()) { get(); this.setIndeterminate(true); ImageIO.write(backgroundImage, fileFormat, new File(filePath)); // create world file for image file String worldFilePath = WorldFileExporter.constructPath(filePath); Grid dem = model.getGeneralizedGrid(); double cellSize = dem.getCellSize(); // for each grid value, one image cell is contructed. The extent // of the image is therefore one pixel larger horizontally and // vertically. double west = dem.getWest() - cellSize / 2; double north = dem.getNorth() + cellSize / 2; WorldFileExporter.writeWorldFile(worldFilePath, cellSize, west, north); } } catch (Exception ignore) { } finally { completeProgress(); } } } private void saveImage(String format, String message) { String filePath = askFile(message, false); // file selection dialog // make sure the choice is a valid file if (filePath != null) { filePath = FileUtils.forceFileNameExtension(filePath, format); // render to image with the same size as the input grid // instead of using navigableImagePanel.getImage(), which can // have a different size BufferedImage img = model.createDestinationImage(1); new FileRenderer(img, filePath, format, this).execute(); } } private void saveTIFFImageMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTIFFImageMenuItemActionPerformed saveImage("tif", "Save TIFF Image"); }//GEN-LAST:event_saveTIFFImageMenuItemActionPerformed private void saveGeneralizedGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveGeneralizedGridMenuItemActionPerformed saveTerrain(model.getGeneralizedGrid()); }//GEN-LAST:event_saveGeneralizedGridMenuItemActionPerformed private void openMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openMenuItemActionPerformed openGrid(); }//GEN-LAST:event_openMenuItemActionPerformed private void infoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_infoMenuItemActionPerformed ProgramInfoPanel.showApplicationInfo(this); }//GEN-LAST:event_infoMenuItemActionPerformed private void terrainInfoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_terrainInfoMenuItemActionPerformed StringBuilder sb = new StringBuilder(); sb.append("<html> <b>"); sb.append(getTitle()); sb.append("</b><br>"); sb.append(model.getGrid().getDescriptionWithStatistics("<br>")); String title = "Terrain Model Info"; JOptionPane.showMessageDialog(this, sb.toString(), title, JOptionPane.PLAIN_MESSAGE); }//GEN-LAST:event_terrainInfoMenuItemActionPerformed private void settingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_settingsMenuItemActionPerformed settingsDialog.setVisible(!settingsDialog.isVisible()); }//GEN-LAST:event_settingsMenuItemActionPerformed private void infoMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_infoMenuMenuSelected boolean gridLoaded = (model.getGrid() != null); terrainInfoMenuItem.setEnabled(gridLoaded); boolean settingsVisible = settingsDialog.isVisible(); settingsMenuItem.setText(settingsVisible ? "Hide Settings" : "Show Settings"); }//GEN-LAST:event_infoMenuMenuSelected private void viewResetMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewResetMenuItemActionPerformed navigableImagePanel.setZoom(0); }//GEN-LAST:event_viewResetMenuItemActionPerformed private void viewZoomInMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewZoomInMenuItemActionPerformed navigableImagePanel.setZoom(navigableImagePanel.getZoom() + navigableImagePanel.getZoomIncrement()); }//GEN-LAST:event_viewZoomInMenuItemActionPerformed private void viewZoomOutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewZoomOutMenuItemActionPerformed navigableImagePanel.setZoom(navigableImagePanel.getZoom() - navigableImagePanel.getZoomIncrement()); }//GEN-LAST:event_viewZoomOutMenuItemActionPerformed private void savePNGImageMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePNGImageMenuItemActionPerformed saveImage("png", "Save PNG Image"); }//GEN-LAST:event_savePNGImageMenuItemActionPerformed /** * Render an image and write it to a file, while a progress dialog with a * cancel button is displayed. * * @param filePath file to write to. * @param scale The final image will be this many times larger than the * terrain model. */ private void exportContours(final String filePath, final String imageFormat, final int scale) { String dialogTitle = "Contours Export"; SwingWorkerWithProgressIndicatorDialog worker; worker = new SwingWorkerWithProgressIndicatorDialog<Void>(this, dialogTitle, "", true) { @Override public void done() { try { // a call to get() will throw an ExecutionException if an // exception occured in doInBackground get(); // create world file for image file String worldFilePath = WorldFileExporter.constructPath(filePath); Grid dem = model.getGeneralizedGrid(); double cellSize = dem.getCellSize() / scale; double west = dem.getWest() - cellSize / 2; double north = dem.getNorth() + cellSize / 2; WorldFileExporter.writeWorldFile(worldFilePath, cellSize, west, north); } catch (ExecutionException e) { // an exception was thrown in doInBackground new File(filePath).delete(); String msg = "An error occured when exporting the image."; String title = "Export Error"; JOptionPane.showMessageDialog(getContentPane(), msg, title, JOptionPane.ERROR_MESSAGE); } catch (InterruptedException | CancellationException e) { } catch (IOException exc) { new File(filePath).delete(); } finally { // hide the progress dialog completeProgress(); } } @Override protected Void doInBackground() throws Exception { // initialize the progress dialog start(); // compute the image with illuminated contours IlluminatedContoursOperator op; boolean illuminated = (model.foregroundVisualization == ForegroundVisualization.ILLUMINATED_CONTOURS); op = model.setupIlluminatedContoursOperator(illuminated); int w = model.getGeneralizedGrid().getCols() * scale; int h = model.getGeneralizedGrid().getRows() * scale; BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); op.renderToImage(image, model.getGeneralizedGrid(), model.getGeneralizedSlopeGrid(), this); if (!isCancelled()) { // writing to file cannot be canceled setCancellable(false); setIndeterminate(true); File file = new File(filePath); setMessage("Writing image to \"" + file.getName() + "\""); ImageIO.write(image, imageFormat, file); } return null; } }; worker.setMaxTimeWithoutDialogMilliseconds(500); worker.setIndeterminate(false); worker.setMessage("Computing contours image"); worker.execute(); } private void saveContours(String askFileMessage, String imageFormat) { String PREFS_NAME = "contours_scale"; String filePath = askFile(askFileMessage, false); if (filePath != null) { filePath = FileUtils.forceFileNameExtension(filePath, imageFormat); String title = "Image Resolution"; Preferences prefs = Preferences.userNodeForPackage(MainWindow.class); imageResolutionSpinner.setValue(prefs.getInt(PREFS_NAME, 5)); int res = JOptionPane.showOptionDialog(getContentPane(), imageResolutionPanel, title, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, null, null); if (res == JOptionPane.OK_OPTION) { int scale = (Integer) (imageResolutionSpinner.getValue()); exportContours(filePath, imageFormat, scale); prefs.putInt(PREFS_NAME, scale); } } } private void saveTIFFContoursMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTIFFContoursMenuItemActionPerformed saveContours("Save TIFF Contour Image", "tif"); }//GEN-LAST:event_saveTIFFContoursMenuItemActionPerformed private void savePNGContoursMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePNGContoursMenuItemActionPerformed saveContours("Save PNG Contour Image", "png"); }//GEN-LAST:event_savePNGContoursMenuItemActionPerformed private void fileMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_fileMenuMenuSelected boolean gridLoaded = (model.getGrid() != null); boolean contoursVisible = model.foregroundVisualization != Model.ForegroundVisualization.NONE; saveGridMenuItem.setEnabled(gridLoaded); saveGeneralizedGridMenuItem.setEnabled(gridLoaded); saveLocalGridMenuItem.setEnabled(model.backgroundVisualization.isLocal()); saveDownsampledMenu.setEnabled(gridLoaded); saveTIFFImageMenuItem.setEnabled(gridLoaded); savePNGImageMenuItem.setEnabled(gridLoaded); saveTIFFContoursMenuItem.setEnabled(contoursVisible); savePNGContoursMenuItem.setEnabled(contoursVisible); saveTIFFNormalMapMenuItem.setEnabled(gridLoaded); savePNGNormalMapMenuItem.setEnabled(gridLoaded); }//GEN-LAST:event_fileMenuMenuSelected private void viewMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_viewMenuMenuSelected boolean gridLoaded = (model.getGrid() != null); viewResetMenuItem.setEnabled(gridLoaded); viewZoomInMenuItem.setEnabled(gridLoaded); viewZoomOutMenuItem.setEnabled(gridLoaded); }//GEN-LAST:event_viewMenuMenuSelected private void saveLocalGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveLocalGridMenuItemActionPerformed saveTerrain(model.getLocalGrid()); }//GEN-LAST:event_saveLocalGridMenuItemActionPerformed private void scaleGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_scaleGridMenuItemActionPerformed int option = JOptionPane.showOptionDialog(this, scaleGridPanel, "Scale Terrain", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (option != JOptionPane.OK_OPTION) { return; } try { scaleTerrainFormattedTextField.commitEdit(); java.lang.Number f = (java.lang.Number) (scaleTerrainFormattedTextField.getValue()); float scale = f.floatValue(); model.scaleGrid(scale); settingsDialog.modelChanged(); } catch (Exception exc) { ErrorDialog.showErrorDialog("An error occured while scaling the terrain.", "Error", exc, this); } }//GEN-LAST:event_scaleGridMenuItemActionPerformed private void offsetGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_offsetGridMenuItemActionPerformed int option = JOptionPane.showOptionDialog(this, offsetGridPanel, "Vertically Offset Terrain", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (option != JOptionPane.OK_OPTION) { return; } try { offsetTerrainFormattedTextField.commitEdit(); java.lang.Number f = (java.lang.Number) (offsetTerrainFormattedTextField.getValue()); float offset = f.floatValue(); model.verticallyOffsetGrid(offset); settingsDialog.modelChanged(); } catch (Exception exc) { ErrorDialog.showErrorDialog("An error occured while changing the terrain.", "Error", exc, this); } }//GEN-LAST:event_offsetGridMenuItemActionPerformed private void editMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_editMenuMenuSelected boolean gridLoaded = (model.getGrid() != null); scaleGridMenuItem.setEnabled(gridLoaded); offsetGridMenuItem.setEnabled(gridLoaded); voidGridMenuItem.setEnabled(gridLoaded); }//GEN-LAST:event_editMenuMenuSelected /** * Draw a set of lines into an image * * @param img * @param lines * @param grid */ private static void drawLines(BufferedImage img, GeometryCollection lines, Grid grid) { int imageHeight = img.getHeight(); Graphics2D g2 = (Graphics2D) img.getGraphics(); RenderingHints rh = new RenderingHints( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHints(rh); g2.setStroke(new BasicStroke(3)); g2.setColor(Color.BLACK); double dx = grid.getWest(); double sx = img.getWidth() / (grid.getEast() - grid.getWest()); double dy = grid.getSouth(); double sy = img.getHeight() / (grid.getNorth() - grid.getSouth()); int nLines = lines.getNumGeometries(); for (int lineID = 0; lineID < nLines; lineID++) { LineString line = (LineString) lines.getGeometryN(lineID); int nPoints = line.getNumPoints(); GeneralPath path = new GeneralPath(); Point pt = line.getFirstPoint(); double x = (pt.getX() - dx) * sx; double y = (pt.getY() - dy) * sy; path.moveTo(x, imageHeight - y); for (int pointID = 1; pointID < nPoints; pointID++) { pt = line.getPointN(pointID); x = (pt.getX() - dx) * sx; y = (pt.getY() - dy) * sy; path.lineTo(x, imageHeight - y); } g2.draw(path); } g2.dispose(); } private void planObliqueFeaturesMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_planObliqueFeaturesMenuItemActionPerformed try { // erase previously drawn lines navigableImagePanel.repaint(); if (model.planObliqueAngle == 90) { String msg = "Please first adjust the plan oblique relief angle."; String title = "Plan Oblique Lines"; JOptionPane.showMessageDialog(getContentPane(), msg, title, JOptionPane.WARNING_MESSAGE); return; } // ask the user for a file to read String filePath = askFile("Select a Line Shapefile", true); if (filePath == null) { // user canceled return; } GeometryCollectionImporter importer = new ShapeImporter(); GeometryCollection vectors = importer.importData(filePath); // test whether the vector geometry intersects with the grid Rectangle2D vectorsBB = vectors.getBoundingBox(); Rectangle2D gridBB = model.getGeneralizedGrid().getBoundingBox(); if (GeometryUtils.rectanglesIntersect(gridBB, vectorsBB) == false) { String msg = "<html>The shapefile geometry does not align with " + "the terrain model.<br>It is likely that the shapefile " + "and the grid use different coordinate systems."; String title = "Data Misalignment"; JOptionPane.showMessageDialog(getContentPane(), msg, title, JOptionPane.ERROR_MESSAGE); return; } // ask the user whether occluded line segments are to be clipped String[] options = new String[]{"Clip", "Do Not Clip", "Cancel"}; String title = "Occlusion Clipping"; String msg = "Clip occluded line segments?"; int lineClipping = JOptionPane.showOptionDialog(getContentPane(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]); if (lineClipping == 2) { // user canceled return; } // apply shearing PlanObliqueShearing shearingOp = new PlanObliqueShearing( model.planObliqueAngle, model.getGeneralizedGrid(), model.getGeneralizedGrid().getMinMax()[0], lineClipping == 0); GeometryCollection shearedLines = shearingOp.shear(vectors); BufferedImage img = navigableImagePanel.getImage(); drawLines(img, shearedLines, model.getGeneralizedGrid()); navigableImagePanel.repaint(); // ask the user for a file to save filePath = askFile("Save Plan Oblique Lines", false); if (filePath == null) { // user canceled return; } filePath = FileUtils.forceFileNameExtension(filePath, "shp"); ShapeExporter geometryExporter = new ShapeExporter(); geometryExporter.export(shearedLines, filePath); geometryExporter.exportTableForGeometry(filePath, shearedLines, ""); } catch (IOException ex) { Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex); } }//GEN-LAST:event_planObliqueFeaturesMenuItemActionPerformed private void saveDownsampledMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_saveDownsampledMenuMenuSelected saveDownsampledMenu.removeAll(); if (model == null || model.laplacianPyramid == null) { return; } Grid[] levels = model.laplacianPyramid.getLevels(); for (int i = 0; i < levels.length; i++) { String str = levels[i].getCols() + "\u00D7" + levels[i].getRows(); if (i == 0) { str += " (Full Resolution)"; } JMenuItem menuItem = new JMenuItem(str); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // weights for Laplacian pyramid levels float[] w = model.laplacianPyramid.createConstantWeights(1f); for (int j = 0; j < saveDownsampledMenu.getMenuComponentCount(); j++) { Component comp = saveDownsampledMenu.getMenuComponent(j); if (comp == e.getSource()) { Arrays.fill(w, 0, j, 0f); break; } } saveTerrain(model.laplacianPyramid.sumLevels(w, false)); } }); saveDownsampledMenu.add(menuItem); } }//GEN-LAST:event_saveDownsampledMenuMenuSelected private void saveNormalMap(String format) { String filePath = askFile("Normal Map", false); if (filePath != null) { filePath = FileUtils.forceFileNameExtension(filePath, format); try { BufferedImage img = model.createDestinationImage(1); NormalMapOperator op = new NormalMapOperator(Channel.R, Channel.G, Channel.B, false, false, false, 1f); op.operate(model.getGeneralizedGrid(), img, model.shadingVerticalExaggeration); ImageIO.write(img, format, new File(filePath)); // create world file for image file String worldFilePath = WorldFileExporter.constructPath(filePath); Grid dem = model.getGeneralizedGrid(); double cellSize = dem.getCellSize(); // for each grid value, one image cell is contructed. The extent // of the image is therefore one pixel larger horizontally and // vertically. double west = dem.getWest() - cellSize / 2; double north = dem.getNorth() + cellSize / 2; WorldFileExporter.writeWorldFile(worldFilePath, cellSize, west, north); } catch (IOException ex) { ErrorDialog.showErrorDialog(SAVE_IMAGE_ERROR_MESSAGE, "Error", ex, this); } } } private void saveTIFFNormalMapMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveTIFFNormalMapMenuItemActionPerformed saveNormalMap("tif"); }//GEN-LAST:event_saveTIFFNormalMapMenuItemActionPerformed private void savePNGNormalMapMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePNGNormalMapMenuItemActionPerformed saveNormalMap("png"); }//GEN-LAST:event_savePNGNormalMapMenuItemActionPerformed private void voidGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_voidGridMenuItemActionPerformed int option = JOptionPane.showOptionDialog(this, voidGridPanel, "Void Values", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (option != JOptionPane.OK_OPTION) { return; } try { voidGridFormattedTextField.commitEdit(); java.lang.Number f = (java.lang.Number) (voidGridFormattedTextField.getValue()); model.voidGridValue(f.floatValue()); settingsDialog.modelChanged(); } catch (Exception exc) { ErrorDialog.showErrorDialog("An error occured while changing the terrain.", "Error", exc, this); } }//GEN-LAST:event_voidGridMenuItemActionPerformed private void saveGridMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveGridMenuItemActionPerformed saveTerrain(model.getGrid()); }//GEN-LAST:event_saveGridMenuItemActionPerformed private void savePlanObliqueMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_savePlanObliqueMenuItemActionPerformed Grid grid = model.getGrid(); if (model.planObliqueAngle != 90) { float min = grid.getMinMax()[0]; PlanObliqueOperator planObliqueOp = new PlanObliqueOperator(model.planObliqueAngle, min); grid = planObliqueOp.operate(grid); } saveTerrain(grid); }//GEN-LAST:event_savePlanObliqueMenuItemActionPerformed /** * Ask the user for a file to read or write. * * @param frame A Frame for which to display the dialog. * @param message A message that will be displayed in the dialog. * @param load Pass true if an existing file for reading should be selected. * Pass false if a new file for writing should be specified. * @return A path to the file, including the file name. */ private String askFile(String message, boolean load) { int flag = load ? java.awt.FileDialog.LOAD : java.awt.FileDialog.SAVE; // display the dialog java.awt.FileDialog fd = new java.awt.FileDialog(this, message, flag); fd.setVisible(true); // construct the path to the file that the user selected. String fileName = fd.getFile(); String directory = fd.getDirectory(); if (fileName == null || directory == null) { return null; } return directory + fileName; } public void initDisplayImage() { // compute a scale factor for the display image // this makes sure contour lines for small grids do not // appear overly pixelated GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); int screenWidth = gd.getDisplayMode().getWidth(); int screenHeight = gd.getDisplayMode().getHeight(); int imageScaleFactor = 1; Dimension dim = model.getGridDimensionForDisplay(); double heightRatio = (double) screenHeight / dim.getHeight(); double widthRatio = (double) screenWidth / dim.getWidth(); double maxRatio = Math.max(heightRatio, widthRatio); if (maxRatio > 1) { imageScaleFactor = (int) Math.ceil(maxRatio); } // initialize the display image BufferedImage image = model.createDestinationImage(imageScaleFactor); navigableImagePanel.setImage(image); } /** * Open a grid file and initialize the data model. * * @param filePath The file to open * @throws IOException */ private void openGrid(final String filePath) throws IOException { SwingWorkerWithProgressIndicatorDialog worker; String dialogTitle = "Pyramid Shader"; worker = new SwingWorkerWithProgressIndicatorDialog<Void>(this, dialogTitle, "", true) { @Override public void done() { try { // a call to get() will throw an ExecutionException if an // exception occured in doInBackground get(); // hide the progress dialog before rendering the image // if rendering throws an error, the progress dialog should // have been closed completeProgress(); // set window title to file name setTitle(filePath.substring(filePath.lastIndexOf(File.separator) + 1)); // add document to Open Recent menu rdm.addDocument(new File(filePath), null); } catch (InterruptedException | CancellationException e) { return; } catch (Throwable e) { // hide the progress dialog completeProgress(); // an exception was thrown in doInBackground String msg = "<html>An error occured when importing the terrain model." + "<br>The file must be in Esri ASCII Grid format.</html>"; ErrorDialog.showErrorDialog(msg, "Error", null, getContentPane()); return; } finally { // hide the progress dialog completeProgress(); } try { initDisplayImage(); // this will render the image settingsDialog.modelChanged(); // display warning when value range in grid is so low that // shading does not show any variation float[] minMax = model.getGrid().getMinMax(); float range = minMax[1] - minMax[0]; if (range < model.getGrid().getCellSize() * 2) { String msg = "<html>" + "This grid is rather flat and the shading may " + "not show any variation." + "<br>Use <i>Edit > " + scaleGridMenuItem.getText() + "</i> to vertically exaggerate the grid." + "</html>"; JOptionPane.showMessageDialog(getContentPane(), msg, "Pyramid Shader", JOptionPane.WARNING_MESSAGE); } } catch (Throwable e) { BufferedImage img = navigableImagePanel.getImage(); if (img != null) { Graphics g = img.getGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, img.getWidth(), img.getHeight()); g.dispose(); } String msg = "An error occured when rendering the terrain."; ErrorDialog.showErrorDialog(msg, "Error", e, getContentPane()); assert false : e.getStackTrace(); } } @Override protected Void doInBackground() throws Exception { start(); //import the DEM and create pyramids Grid grid = EsriASCIIGridReader.read(filePath, this); this.setIndeterminate(true); this.setCancellable(false); model.setGrid(grid); return null; } }; worker.setMaxTimeWithoutDialogMilliseconds(2000); worker.setIndeterminate(false); worker.setMessage("Importing Terrain Model"); worker.execute(); } /** * Ask user for grid file, open the file, and initialized data model. */ public void openGrid() { try { // ask the user for a file String filePath = askFile("Select an Esri ASCII Grid", true); if (filePath != null) { openGrid(filePath); } } catch (IOException ex) { ErrorDialog.showErrorDialog(OPEN_ERROR_MESSAGE, "Error", ex, this); } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenu editMenu; private javax.swing.JMenu experimentalMenu; private javax.swing.JPanel imageResolutionPanel; private javax.swing.JSpinner imageResolutionSpinner; private javax.swing.JMenuItem infoMenuItem; private javax.swing.JMenuBar menuBar; private edu.oregonstate.cartography.gui.NavigableImagePanel navigableImagePanel; private javax.swing.JMenuItem offsetGridMenuItem; private javax.swing.JPanel offsetGridPanel; private javax.swing.JFormattedTextField offsetTerrainFormattedTextField; private javax.swing.JMenu openRecentMenu; private javax.swing.JMenuItem planObliqueFeaturesMenuItem; private javax.swing.JMenu saveDownsampledMenu; private javax.swing.JMenuItem saveGeneralizedGridMenuItem; private javax.swing.JMenuItem saveGridMenuItem; private javax.swing.JMenuItem saveLocalGridMenuItem; private javax.swing.JMenuItem savePNGContoursMenuItem; private javax.swing.JMenuItem savePNGImageMenuItem; private javax.swing.JMenuItem savePNGNormalMapMenuItem; private javax.swing.JMenuItem savePlanObliqueMenuItem; private javax.swing.JMenuItem saveTIFFContoursMenuItem; private javax.swing.JMenuItem saveTIFFImageMenuItem; private javax.swing.JMenuItem saveTIFFNormalMapMenuItem; private javax.swing.JMenuItem scaleGridMenuItem; private javax.swing.JPanel scaleGridPanel; private javax.swing.JFormattedTextField scaleTerrainFormattedTextField; private javax.swing.JMenuItem settingsMenuItem; private javax.swing.JMenuItem terrainInfoMenuItem; private javax.swing.JMenu viewMenu; private javax.swing.JMenuItem viewResetMenuItem; private javax.swing.JMenuItem viewZoomInMenuItem; private javax.swing.JMenuItem viewZoomOutMenuItem; private javax.swing.JFormattedTextField voidGridFormattedTextField; private javax.swing.JMenuItem voidGridMenuItem; private javax.swing.JPanel voidGridPanel; // End of variables declaration//GEN-END:variables /** * @return the model */ public Model getModel() { return model; } public void repaintImage() { navigableImagePanel.repaint(); } public BufferedImage getImage() { return navigableImagePanel.getImage(); } void setPreferredImageSize(Dimension dimension) { navigableImagePanel.setPreferredSize(dimension); } /** * @param settingsDialog the settingsDialog to set */ public void setSettingsDialog(SettingsDialog settingsDialog) { this.settingsDialog = settingsDialog; navigableImagePanel.addPropertyChangeListener(settingsDialog); } private void saveTerrain(Grid grid) { //call up a save file dialog String filePath = askFile("Save Terrain File", false); if (filePath != null) { filePath = FileUtils.forceFileNameExtension(filePath, "asc"); try { ESRIASCIIGridExporter.export(grid, filePath); } catch (IOException ex) { ErrorDialog.showErrorDialog(SAVE_TERRAIN_ERROR_MESSAGE, "Error", ex, this); } } } public ProgressPanel getProgressPanel() { return progressPanel; } }